package com.ws.encapsulation;
/*
面向对象的特征一：封装与隐藏
一、问题引入
  当我们创建一个类的对象以后，我们可以通过"对象.属性"的方式，对对象的属性进行赋值。
  这里，赋值操作要受属性的数据类型和存储范围的制约。除此之外，没有其他制约条件。
  但是，在实际问题中，我们往往需要给属性赋值，并加入额外的限制条件。
  这个条件就不能在属性声明时体现，我们只能通过方法进行限制条件的添加。
  (比如: set同时，我们需要避免用户再使用"对象.属性"的方式对属性进行赋值。
  则需要将属性声明为私有的(private)
  -->此时，针对于属性就体现了封装性。

二、封装性的体现：
  我们将属性xx私有化(private)，同时提供公共的(public)方法来获取(getXx)和设置(setXx)此属性
  拓展：封装性的体现：①成员变量的私有化，②方法的私有化，③单例模式 ....

三、作用：
隐藏对象的内部的复杂性，之对外公开简单的接口。便于边界调用，从而提供系统的可扩展性、可维护性。
通俗的说，就是把该隐藏的隐藏起来，该暴露的暴露出来。这就是封装性的设计思想

四、封装性的体现，需要权限修饰符来配合。
1.Java 规定的 4 中权限（从小到大排序）：private、缺省、protected、public
2.4种权限可以用来修饰类及类的内部结构：属性、方法、构造器、内部类
3.4中权限都可以用来修饰类的内部结构：属性、方法、构造器、内部类
  修饰类的话，只能使用：缺省、public

总结封装性：Java提供了四种权限修饰符来修饰类及类的内部结构，体现类及类的内部结构在被调用时的可见性的大小
 */
public class AnimalTest {
    public static void main(String[] args) {

        Animal a = new Animal();
        a.name = "大黄";

        a.setAge(3);
        a.setLegs(4);
        a.show();
    }
}


class Animal {
    String name;
    private int age;
    private int legs;

    //对属性的设置
    public void setLegs(int i) {
        if (i >= 0 && i % 2 == 0) {
            legs = i;
        } else {
            legs = 0;
        }
    }

    //对属性的获取
    public int getLegs() {
        return legs;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public int getAge() {
        return age;
    }

    public void eat() {
        System.out.println("进食");
    }

    public void  show() {
        System.out.println("name = " + name + ", age = " + age + ", legs = " + legs) ;
    }
}